## 修改 [AbilitySystemComponent] 中的 Attribute ,当属性 duration_type 为 Instant 时，
## [Effect] 不会为 [AbilitySystemComponent] 修改Tags，因为这时的Effect不是一个持续的状态，
## 当 duration_type 为 Duration 时，需要指定该状态每次应用的时间间隔(duration)，
## 以及经过多久结束(timeout)，当 duration_type 为 Infinite 时，不需要指定 timeout
@tool
extends Resource
class_name Effect


## 将要修改的属性
@export var attribute_dictionary:AttributeDictionary

enum StackingType{
	## 无叠加
	NONE=-1,
	## 根据 Effect 来源叠加
	BySource,
	## 根据 Effect 目标叠加
	ByTarget}
## Effect 的叠加方式，相互关联的 Effect 将在ASC中根据堆叠方式做不同的处理
@export var stacking_type:StackingType = StackingType.NONE

## 该Effect产生的视听效果
#@export var cues

enum DurationType {
	## 立即应用这个[Effect]
	Instant=-1,
	## 持续应用这个[Effect] 
	Duration,
	## 无限应用这个[Effect]
	Infinite}

## Effect应用的方式,立即(Instant) 、持续(Duration)、永久(Infinite)
@export var duration_type:DurationType = -1:
	set(value):
		duration_type = value
		notify_property_list_changed()

## 重复应用该 [Effect] 的间隔时间
@export var duration:float = 0.0:
	set(value):
		if time_out < value:
			time_out = value
		duration = value
	get():
		return duration


## 应用此Effect时将被添加的Tag
@export var tags_to_add:Array[String]

## 应用此Effect时将被移除的Tag
@export var tags_to_remove:Array[String]


## 简单计算方式
@export var modifiers:Array[Modifier]

## 复杂的计算方式,使用此方式计算时忽略 modifiers 中的配置
@export var executions:Array[Execution]

# 周期枚举
enum PeriodType{
	NeverReset = -1,
	ResetPeriod,
	ExecuteAndResetPeriod
}
## 周期配置
@export var period:PeriodType = -1:
	set(value):
		period = value
		notify_property_list_changed()

## 重复应用该 [Effect] 时，将在多久之后结束
@export var time_out:float = 0.0:
	set(value):
		if value > duration:
			time_out = value
		else:
			time_out = duration


# 加载属性列表
func _validate_property(property: Dictionary) -> void:
	var hidden_list = []
	match duration_type:
		DurationType.Instant:
			hidden_list.append("duration")
			hidden_list.append("tags_to_add")
			hidden_list.append("tags_to_remove")
		DurationType.Infinite:
			hidden_list.append("time_out")
	match period:
		PeriodType.NeverReset:
			hidden_list.append("time_out")
			
	# property中的name属性存在于列表中，则将其设置为不显示
	if property.name in hidden_list:
		property.usage = PROPERTY_USAGE_NO_EDITOR
